import logging
import uuid
from contextlib import asynccontextmanager
from config.scheduler import scheduler
from config.db_scheduler import db_scheduler
from config.tasks import simple_task,task_with_params,log_task,http_request_task,data_processing_task,database_cleanup_task
from models.schemas import JobCreate,JobUpdate,JobResponse
from config.Database import get_session
from models.models import ScheduledJob
from sqlmodel import select

from fastapi import APIRouter, HTTPException, status, Depends
from sqlmodel import Session

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)

@asynccontextmanager
async def start_scheduler(router: APIRouter):
    await scheduler.start()
    await db_scheduler.start()
    yield
    await scheduler.shutdown()
    await db_scheduler.shutdown()

router = APIRouter(lifespan=start_scheduler)

@router.post("/simple")
async def add_simple_job(seconds: int = 10, job_id: str |  None = None):
    """添加简单定时任务"""
    job = scheduler.add_simple_job(simple_task, seconds, job_id)
    return {"message": f"添加简单任务成功，任务ID为：{job.id}"}

@router.get("/jobs")
async def list_jobs():
    """列出所有任务"""
    return scheduler.list_jobs()

@router.delete("/jobs/{job_id}")
async def remove_job(job_id: str):
    """删除任务"""
    result = scheduler.remove_job(job_id)
    if not result:
        raise HTTPException(status_code=404, detail=f"任务{job_id}不存在")
    return {"message": f"任务{job_id}已删除"}

# 注册任务函数
db_scheduler.register_task("log_task", log_task)
db_scheduler.register_task("http_request_task", http_request_task)
db_scheduler.register_task("data_processing_task", data_processing_task)
db_scheduler.register_task("database_cleanup_task", database_cleanup_task)

@router.post("/v2/jobs",status_code=status.HTTP_201_CREATED)
async def create_job(job: JobCreate, db:Session = Depends(get_session)):
    """创建定时任务"""
    # 生成一个唯一的job_id
    job_id = f"job_{uuid.uuid4().hex[:8]}"
    # 验证任务函数
    if job.task_function not in db_scheduler.task_functions:
        raise HTTPException(status_code=400, detail=f"任务函数{job.task_function}未注册")
    success = False
    if job.cron_expression:
        # 创建cron任务
        success = db_scheduler.add_cron_job(
            task_name=job.task_function,
            cron_expression=job.cron_expression,
            job_id=job_id,
            name=job.name,
            job_args=job.job_args,
            job_kwargs=job.job_kwargs,
            db=db
        )
    elif job.interval_seconds:
        # 创建interval任务
        success = db_scheduler.add_interval_job(
            task_name=job.task_function,
            seconds=job.interval_seconds,
            job_id=job_id,
            name=job.name,
            job_args=job.job_args,
            job_kwargs=job.job_kwargs,
            db=db
        )
    else:
        raise HTTPException(status_code=400, detail="必须提供cron_expression或interval_seconds")

    if success:
        return {
            "message": f"任务{job_id}创建成功",
            "job_id": job_id
        }
    raise HTTPException(status_code=500, detail="任务创建失败")


@router.get("/v2/jobs", response_model=list[JobResponse])
async def list_jobs(db:Session = Depends(get_session)):
    """列出所有定时任务"""
    jobs = db_scheduler.list_jobs(db)
    print("jobs:",  jobs)
    return jobs

@router.get("/v2/jobs/{job_id}", response_model=JobResponse)
async def get_job(job_id: str, db:Session = Depends(get_session)):
    """获取指定任务"""
    try:
        aps_job = db_scheduler.scheduler.get_job(job_id)
        if not aps_job:
            raise HTTPException(status_code=404, detail=f"任务{job_id}不存在")

        job_info = {
            "id": aps_job.id,
            "name": aps_job.name,
            "next_run_time": aps_job.next_run_time.strftime('%Y-%m-%d %H:%M:%S') if aps_job.next_run_time else None,
            "trigger": str(aps_job.trigger),
            "pending": aps_job.pending
        }
        # 从数据库中获取额外信息
        statement = select(ScheduledJob).where(ScheduledJob.job_id == job_id)
        db_job = db.exec(statement).first()
        if db_job:
            job_info.update({
                "is_active": db_job.is_active,
                "task_function": db_job.task_function,
                "created_time": db_job.created_time.strftime('%Y-%m-%d %H:%M:%S') if db_job.created_time else None,
            })
        return job_info
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/v2/jobs/{job_id}/pause")
async def pause_job(job_id: str, db:Session = Depends(get_session)):
    """暂停指定任务"""
    try:
        result = db_scheduler.pause_job(job_id, db)
        if not result:
            raise HTTPException(status_code=404, detail=f"任务{job_id}不存在")
        return {"message": f"任务{job_id}已暂停"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.put("/v2/jobs/{job_id}/resume")
async def resume_job(job_id: str, db:Session = Depends(get_session)):
    """恢复指定任务"""
    try:
        result = db_scheduler.resume_job(job_id, db)
        if not result:
            raise HTTPException(status_code=404, detail=f"任务{job_id}不存在")
        return {"message": f"任务{job_id}已恢复"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.put("/v2/jobs/{job_id}/cron")
async def modify_job_cron(job_id: str, cron_expression: str, db:Session = Depends(get_session)):
    """修改指定任务的cron表达式"""
    try:
        result = db_scheduler.modify_job_cron(job_id, cron_expression, db)
        if not result:
            raise HTTPException(status_code=404, detail=f"任务{job_id}不存在")
        return {"message": f"任务{job_id}的cron表达式已修改"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@router.delete("/v2/jobs/{job_id}")
async def remove_job(job_id: str, db:Session = Depends(get_session)):
    """删除指定任务"""
    try:
        result = db_scheduler.remove_job(job_id, db)
        if not result:
            raise HTTPException(status_code=404, detail=f"任务{job_id}不存在")
        return {"message": f"任务{job_id}已删除"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))